package com.polaris.live.ui.live.widget

import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.RelativeLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.viewModelScope
import com.bumptech.glide.Glide
import com.polaris.live.R
import com.polaris.live.cache.CommonCache
import com.polaris.live.common.constant.AppConst
import com.polaris.live.common.constant.PagConst.LIVING_CALL_PAG
import com.polaris.live.common.constant.PagConst.LIVING_GIFT_PAG
import com.polaris.live.common.ext.autoDp
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.mvvm.viewmodel.BaseViewModel
import com.polaris.live.constant.LiveConst
import com.polaris.live.constant.LiveConst.LivePage
import com.polaris.live.constant.LiveConst.Page
import com.polaris.live.databinding.WidgetLiveFooterBinding
import com.polaris.live.dialog_fragment.GiftDialogFragment
import com.polaris.live.im.manager.ImSessionManager
import com.polaris.live.im.sfs.bean.live.LiveRoomInfo
import com.polaris.live.popup.GameListPopup
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.resp.back_resp.UserFreeGiftResp
import com.polaris.live.resp.back_resp.UserRoomThemeResp
import com.polaris.live.resp.bean.GiftSendBean
import com.polaris.live.resp.go_resp.SendGiftBean
import com.polaris.live.ui.game.GameUtils
import com.polaris.live.ui.live.widget.listener.OnGameClickListener
import com.polaris.live.ui.live.widget.listener.OnSendGiftListener
import com.polaris.live.utils.BitwiseUtils
import com.polaris.live.utils.TaskRedProxy
import com.polaris.live.utils.fragment.FragmentUtils
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.widget.circle.CircleCountDownView
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

/**
 * LiveFooterView
 *
 * @author Created by lucas on 2023/11/7 15:34
 */
class LiveFooterView(context: Context, attributeSet: AttributeSet) :
    RelativeLayout(context, attributeSet) {

    val mBinding = WidgetLiveFooterBinding.inflate(LayoutInflater.from(context), this)

    private var mLiveInfo: LiveRoomInfo? = null
    private var mUserInfo: InfoOtherResp? = null

    private var mComboView: CircleCountDownView? = null

    //记录上次发送的礼物
    private var giftSendBean: GiftSendBean? = null

    private var mOnSendGiftListener: OnSendGiftListener? = null

    //游戏点击回调
    private var mOnGameClickListener: OnGameClickListener? = null

    private var mObservedSession: Boolean = false

    private var mViewModel: BaseViewModel? = null
    private var mPage: Int? = null

    private var freeGiftJob: Job? = null

    private val mGiftDialog by lazy {
        GiftDialogFragment(
            AppConst.GiftComming.LIVE,
            AppConst.BackpackGiftComming.LIVE,
            mLiveInfo?.userId,
            true
        ) { giftSendBean ->

            val liveInfo = mLiveInfo ?: return@GiftDialogFragment

            val sendGiftBean =
                SendGiftBean(
                    liveInfo.userId,
                    giftSendBean.gift.id,
                    giftSendBean.num,
                    AppConst.GiftComming.LIVE,
                    liveInfo.liveId,
                    giftSendBean.backpackId,
                    giftSendBean.gift.payload
                )
            mOnSendGiftListener?.onSendGift(sendGiftBean)
            this.giftSendBean = giftSendBean
        }
    }

    fun upBackpackIdAllCount(backpackId: Long?, ext: Map<String, Any>? = null) {
        if (backpackId != null) {
            val amount =
                (ext?.get("backpackAccount") as? Map<*, *>)?.get("amount")?.toString()
                    ?.toDoubleOrNull()?.toLong()
            if (amount != null) {
                mGiftDialog.upBackpackIdAllCount(backpackId, amount)
            }
        }
    }

    fun isShowComboView(): Boolean {
        return when {
            giftSendBean == null -> false
            giftSendBean?.isAll == true -> false
            giftSendBean?.backpackId == null -> true
            else -> {
                val giftType = giftSendBean!!.gift.type
                BitwiseUtils.isBitwise(giftType, LiveConst.LUCKY_GIFTS.toInt()) ||
                        BitwiseUtils.isBitwise(giftType, LiveConst.LUCKY_BACKPACK_GIFT.toInt())
            }
        }
    }

    init {
        //点开礼物列表
        mBinding.ivGift.setOnSingleClickListener {
            showGiftDialog(null)
        }
        //点开游戏弹窗
        mBinding.ivGame.setOnSingleClickListener {
            if (mOnGameClickListener == null) {
                val roomId = (mLiveInfo?.userId ?: "").toString()
                GameListPopup.show(context, GameUtils.getLiveCacheGameList(), roomId)
            } else {
                mOnGameClickListener?.onClickGameListener()
            }
        }

        mBinding.ivCall.apply {
            path = LIVING_CALL_PAG
            setRepeatCount(-1)
            play()
        }

        mBinding.giftPag.apply {
            path = LIVING_GIFT_PAG
            setRepeatCount(-1)
            play()
        }

        updateGameState(!GameUtils.getLiveCacheGameList().isNullOrEmpty())

    }

    /**
     * 设置背包红点
     */
    fun setBackPackRed(visibility: Int) {
        mBinding.backpackRed.visibility = visibility
    }

    /**
     * 设置更多红点
     */
    fun setMoreRed(visibility: Int) {
        mBinding.moreRed.visibility = visibility
    }

    fun initUI(@LivePage page: Int, viewModel: BaseViewModel) {
        this.mViewModel = viewModel
        this.mPage = page
        mBinding.apply {
            //如果是观众
            if (page == Page.LIVE_SPECTATOR) {
                ivGift.visibility = VISIBLE
                ivMore.visibility = VISIBLE
            }
            //是主播
            else {
                if (page == Page.LIVE_MATCH) {
                    ivSend.visibility = GONE
                }
                ivCall.visibility = GONE
                ivGift.visibility = GONE
            }
            updateMessageNumber(ImSessionManager.getTotalUnreadCount())
            observeSession()
        }
        setMoreRed(if (TaskRedProxy.isRedAvailable()) View.VISIBLE else View.GONE)
    }

    fun initData(liveInfo: LiveRoomInfo) {
        mLiveInfo = liveInfo
        val page = mPage
        val viewModel = mViewModel
        if (page != null && page == Page.LIVE_SPECTATOR && viewModel != null) {
            mBinding.widgetCircleGift.setOnShowViewCallback {
                val isNeedShow = CommonCache.getShowFreeGiftTip()
                if (!isNeedShow) {
                    CommonCache.saveShowFreeGiftTip(true)
                    mBinding.widgetCircleGift.post {
                        val rightMargin =
                            mBinding.llItem.width - mBinding.widgetCircleGift.right + (mBinding.widgetCircleGift.width / 2) - 3.autoDp
                        val layoutParam = mBinding.ivBottom.layoutParams as ConstraintLayout.LayoutParams
                        layoutParam.marginEnd = rightMargin
                        mBinding.ivBottom.layoutParams = layoutParam
                        mBinding.cosTip.visibility = View.VISIBLE
                    }
                    shakeView()
                    freeGiftJob = viewModel.viewModelScope.launch {
                        delay(10000)
                        withContext(CoroutineScopeManager.mainDispatcher) {
                            mBinding.cosTip.visibility = GONE
                        }
                    }
                }
            }
        }
    }

    fun shakeView() {
        // 创建ObjectAnimator
        val shake = ObjectAnimator.ofFloat(mBinding.cosTip, "translationY", 0f, 20f, 0f)
        shake.duration = 2500 // 动画持续时间
        shake.interpolator = LinearInterpolator() // 设置平滑过渡
        shake.repeatCount = ObjectAnimator.INFINITE // 无限循环
        shake.repeatMode = ObjectAnimator.RESTART // 重复模式为重启
        shake.start() // 启动动画
    }

    fun setUserData(user: InfoOtherResp) {
        if (mLiveInfo?.userId == user.userId) {
            mUserInfo = user
        }
    }

    fun reset() {
        mLiveInfo = null
        mUserInfo = null
    }

    private fun observeSession() {
        if (mObservedSession) {
            return
        }

        val context = context
        if (context !is LifecycleOwner) {
            throw IllegalStateException("context must be LifecycleOwner")
        }
        ImSessionManager.observeUnreadCount(context) { totalUnreadCount, _, _, _ ->
            updateMessageNumber(totalUnreadCount)
        }

        mObservedSession = true
    }

    private fun updateMessageNumber(number: Long) {
        if (number == 0L) {
            mBinding.ivMessageNumber.visibility = View.INVISIBLE
        } else {
            mBinding.ivMessageNumber.visibility = View.VISIBLE
            mBinding.ivMessageNumber.text = if (number > 99) {
                "99+"
            } else {
                number.toString()
            }
        }
    }

    fun changeFreeGift() {
        mViewModel?.let { mBinding.widgetCircleGift.initFreeGift(AppConst.BackpackGiftComming.LIVE, it) }
    }

    fun updateGameState(hasGame: Boolean) {
        mBinding.ivGame.visibility = if (hasGame) VISIBLE else GONE
    }

    fun attachEditView(editView: LiveEditView) {
        mBinding.ivSend.setOnSingleClickListener {
            editView.showKeyboard()
        }
    }

    fun attachComboView(comboView: CircleCountDownView) {
        mComboView = comboView

        //连点按钮
        comboView.setOnClickListener {
            if (mComboView?.isVisible != true) {
                return@setOnClickListener
            }

            mComboView?.anewRun()
            val giftPayload = giftSendBean
            if (giftPayload != null) {
                val gift = giftPayload.gift
                val sendGiftBean = mLiveInfo?.let {
                    SendGiftBean(
                        it.userId,
                        gift.id,
                        giftPayload.num,
                        AppConst.GiftComming.LIVE,
                        it.liveId,
                        giftPayload.backpackId,
                        gift.payload
                    )
                }
                if (sendGiftBean != null) {
                    mOnSendGiftListener?.onSendGift(sendGiftBean)
                }
            }
        }
    }

    fun showGiftDialog(userInfo: InfoOtherResp?, giftId: Long = -1, giftType: Int = -1) {
        val avatar = userInfo?.avatar ?: mLiveInfo?.avatar ?: return
        val avatarFrame = userInfo?.decoration?.avatarFrame ?: mLiveInfo?.avatarFrame
        val userId = userInfo?.userId ?: mLiveInfo?.userId
        val nickname = userInfo?.nickname ?: mLiveInfo?.nickname
        mComboView?.viewGone()

        val fragmentManager = FragmentUtils.getFragmentManager(context)
            ?: return
        mGiftDialog.apply {
            setAvatar(avatar, avatarFrame)
            setSelectedGiftId(giftId)
            setSelectedGiftType(giftType)
            userId?.let { setUserId(it, nickname) }
            show(fragmentManager, GiftDialogFragment.FRAGMENT_TAG)
        }
    }

    fun setTheme(resp: UserRoomThemeResp? = null) {
        if (resp != null) {
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.send)).into(mBinding.ivSend)
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.chat)).into(mBinding.ivMessage)
            Glide.with(context).load(ImageUtils.imgPath(resp.prefix + resp.more)).into(mBinding.ivMoreIcon)
        } else {
            mBinding.ivSend.setImageResource(R.drawable.live_btn_comment)
            mBinding.ivMessage.setImageResource(R.drawable.live_btn_message)
            mBinding.ivMoreIcon.setImageResource(R.drawable.live_btn_more)
        }
    }

    fun setOnMessageClickListener(l: OnClickListener) {
        mBinding.ivMessage.setOnSingleClickListener {
            l.onClick(it)
        }
    }

    fun setOnCallClickListener(l: OnClickListener) {
        mBinding.ivCall.setOnSingleClickListener {
            l.onClick(it)
        }
    }

    fun setOnSendGiftListener(l: OnSendGiftListener) {
        this.mOnSendGiftListener = l
    }

    fun setOnMoreClickListener(l: OnClickListener) {
        mBinding.ivMore.setOnSingleClickListener {
            l.onClick(it)
        }
    }

    fun setOnGameClickListener(l: OnGameClickListener) {
        this.mOnGameClickListener = l
    }

    fun setOnFreeGiftListener(back: (UserFreeGiftResp) -> Unit) {
        mBinding.widgetCircleGift.setOnClickGiftListener {
            back.invoke(it)
        }
    }

    override fun onDetachedFromWindow() {
        freeGiftJob?.cancel()
        freeGiftJob = null
        super.onDetachedFromWindow()
    }
}